package ls.jpa.chapter6.service;

import ls.jpa.chapter6.dao.UserInfoDao;
import ls.jpa.chapter6.entity.UserInfo;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.Assert;

import java.util.List;

/**
 * @author Barudisshu
 */
@Service
public class UserInfoService {

    public static final Logger logger = Logger.getLogger(UserInfoService.class);

    @Autowired
    private UserInfoDao userInfoDao;

    public UserInfo save(UserInfo userInfo) {
        return userInfoDao.save(userInfo);
    }

    public Iterable<UserInfo> findAll() {
        return userInfoDao.findAll();
    }

    public Iterable<UserInfo> findAll(PageRequest page) {
        return userInfoDao.findAll(page);
    }

    public UserInfo findByName(String username) {
        return userInfoDao.findByName(username);
    }

    public UserInfo findById(Long id) {
        return userInfoDao.findById(id);
    }

    public UserInfo findByAge(Integer age) {
        return userInfoDao.findByAge(age);
    }

    public Page<UserInfo> findByAge(Integer age, Pageable pageable) {
        return userInfoDao.findByAge(age, pageable);
    }

    public List<UserInfo> findAllCached() {
        return userInfoDao.findAllCached();
    }

    public Integer updateUsername(Long id, String username) {
        return userInfoDao.updateUsername(id, username);
    }

    public UserInfo findByPassword(UserInfo userInfo) {
        return userInfoDao.findByPassword(userInfo);
    }

    public Integer plus(Integer arg) {
        return userInfoDao.explicityNumber(arg);
    }

    /**
     * 事务处理，具有连续性和传递性，本例使用编程式事务定制，注意：
     * 单元测试如果配置有事务，请将其去掉，否则事务有冲突。
     *
     * @param userInfo 用户信息
     * @return 操作对象
     */
    @Transactional
    public UserInfo saveWithAddition(UserInfo userInfo) {

        Assert.notNull(userInfo, "The entities must not be null!");
        userInfoDao.saveWithOption(userInfo);
        if (userInfo.getAge() < 22)
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        return userInfo;
    }

    /**
     * 锁操作
     * @return Long
     */
    public Long count() {
        return userInfoDao.count();
    }

    /**
     * 清除所有缓存
     */
    @Caching(evict = {
            @CacheEvict(value="entityCache", allEntries=true)
    })
    public void flushAllCaches() {
        logger.warn("All caches have been completely flushed");
    }
}
